package cn.wufuqi.recyclerviewbindingadapter.utils

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Bitmap
import android.graphics.NinePatch
import android.graphics.Rect
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.NinePatchDrawable
import android.os.Build
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.annotation.RequiresApi
import androidx.databinding.BindingAdapter
import androidx.recyclerview.widget.RecyclerView
import cn.wufuqi.recyclerviewbindingadapter.R
import cn.wufuqi.recyclerviewbindingadapter.extend.isContextValid
import cn.wufuqi.recyclerviewbindingadapter.extend.setViewData
import cn.wufuqi.recyclerviewbindingadapter.itemuibean.BaseBindingAdapterItem
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget

object ViewBindingExtend {

    @BindingAdapter("alpha")
    @JvmStatic
    fun alpha(view: View, alpha: Float) {
        view.alpha = alpha
    }

    @BindingAdapter("maxLines")
    @JvmStatic
    fun maxLines(view: TextView, maxLines: Int) {
        view.maxLines = maxLines
    }

    @BindingAdapter("layout_width")
    @JvmStatic
    fun layoutWidth(view: View, w: Int) {
        view.layoutParams.width = w
        view.layoutParams = view.layoutParams
    }

    @BindingAdapter("width")
    @JvmStatic
    fun width(view: View, w: Int) {
        view.layoutParams.width = w
        view.layoutParams = view.layoutParams
    }

    @BindingAdapter("layout_marginLeft")
    @JvmStatic
    fun layoutMarginLeft(view: View, l: Int) {
        if (view.layoutParams is ViewGroup.MarginLayoutParams) {
            val lp = view.layoutParams as ViewGroup.MarginLayoutParams
            lp.leftMargin = l
            view.layoutParams = lp
        }
    }

    @BindingAdapter("layout_marginRight")
    @JvmStatic
    fun layoutMarginRight(view: View, r: Int) {
        if (view.layoutParams is ViewGroup.MarginLayoutParams) {
            val lp = view.layoutParams as ViewGroup.MarginLayoutParams
            lp.rightMargin = r
            view.layoutParams = lp
        }
    }

    @BindingAdapter("layout_marginTop")
    @JvmStatic
    fun layoutMarginTop(view: View, t: Int) {
        if (view.layoutParams is ViewGroup.MarginLayoutParams) {
            val lp = view.layoutParams as ViewGroup.MarginLayoutParams
            lp.topMargin = t
            view.layoutParams = lp
        }
    }

    @BindingAdapter("layout_marginBottom")
    @JvmStatic
    fun layoutMarginBottom(view: View, b: Int) {
        if (view.layoutParams is ViewGroup.MarginLayoutParams) {
            val lp = view.layoutParams as ViewGroup.MarginLayoutParams
            lp.bottomMargin = b
            view.layoutParams = lp
        }
    }

    @BindingAdapter("widthdp")
    @JvmStatic
    fun widthdp(view: View, w: Int) {
        view.layoutParams.width = (w * 1.0f).dp2px().toInt()
        view.layoutParams = view.layoutParams
    }

    @BindingAdapter("layout_height")
    @JvmStatic
    fun layoutHeight(view: View, h: Int) {
        view.layoutParams.height = h
        view.layoutParams = view.layoutParams
    }

    @BindingAdapter("height")
    @JvmStatic
    fun height(view: View, h: Int) {
        view.layoutParams.height = h
        view.layoutParams = view.layoutParams
    }

    @BindingAdapter("heightdp")
    @JvmStatic
    fun heightdp(view: View, h: Int) {
        view.layoutParams.height = (h * 1.0f).dp2px().toInt()
        view.layoutParams = view.layoutParams
    }

    @SuppressLint("NotifyDataSetChanged")
    @BindingAdapter("adapter")
    @JvmStatic
    fun adapter(view: RecyclerView, adapter: RecyclerView.Adapter<*>) {
        if (view.adapter == adapter) return
        view.adapter = adapter
        adapter.notifyDataSetChanged()
    }

    @BindingAdapter("layoutManagerObject")
    @JvmStatic
    fun layoutManagerObject(view: RecyclerView, layoutManager: RecyclerView.LayoutManager) {
        //注释掉  以防性能消耗
        if (view.layoutManager == null) {
            view.layoutManager = layoutManager
        }
    }

    @BindingAdapter("image")
    @JvmStatic
    fun setImage(view: ImageView, bitmap: Bitmap) {
        if (view.context.isContextValid()) {
            Glide.with(view.context).load(bitmap).into(view)
        }
    }

    @BindingAdapter("src")
    @JvmStatic
    fun setSrc(view: ImageView, bitmap: Bitmap) {
        if (view.context.isContextValid()) {
            Glide.with(view.context).load(bitmap).into(view)
        }
    }


    @BindingAdapter("image")
    @JvmStatic
    fun setImage(view: ImageView, resId: Int) {
        if (view.context.isContextValid()) {
            Glide.with(view.context).load(resId).into(view)
        }
    }

    @BindingAdapter("background")
    @JvmStatic
    fun setBackground(view: View, @DrawableRes resId: Int) {
        view.setBackgroundResource(resId)
    }

    @BindingAdapter("background")
    @JvmStatic
    fun setBackground(view: View, drawable: Drawable) {
        view.background = drawable
    }

    @BindingAdapter("background")
    @JvmStatic
    fun setBackground(view: View, bitmap: Bitmap) {
        view.background = BitmapDrawable(bitmap)
    }

    @BindingAdapter("background")
    @JvmStatic
    fun setBackground(view: View, url: String) {
        if (!view.context.isContextValid()) {
            return
        }
        Glide.with(view.context)
            .asBitmap()
            .load(url)
            .into(object : CustomTarget<Bitmap>() {
                override fun onResourceReady(
                    resource: Bitmap,
                    transition: com.bumptech.glide.request.transition.Transition<in Bitmap>?
                ) {
                    val ninePatchDrawable = createNinePatchDrawable(view.context, resource)
                    view.background = ninePatchDrawable
                }


                @SuppressLint("UseCompatLoadingForDrawables")
                @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
                override fun onLoadCleared(placeholder: Drawable?) {
                    view.background = view.context.getDrawable(R.color.transparent)
                }
            })

    }

    fun createNinePatchDrawable(context: Context, bitmap: Bitmap): Drawable {
        val chunk = bitmap.ninePatchChunk
        val isNinePatchChunk = NinePatch.isNinePatchChunk(chunk)

        return if (isNinePatchChunk) {
            NinePatchDrawable(context.resources, bitmap, chunk, Rect(), null)
        } else {
            BitmapDrawable(context.resources, bitmap)
        }
    }


    @BindingAdapter("src")
    @JvmStatic
    fun setSrc(view: ImageView, resId: Int) {
        if (view.context.isContextValid()) {
            Glide.with(view.context).load(resId).into(view)
        }
    }

    @BindingAdapter("image")
    @JvmStatic
    fun setImage(view: ImageView, url: String) {
        if (view.context.isContextValid()) {
            Glide.with(view.context).load(url).into(view)
        }
    }

    @BindingAdapter("src")
    @JvmStatic
    fun setSrc(view: ImageView, url: String) {
        if (view.context.isContextValid()) {
            Glide.with(view.context).load(url).into(view)
        }
    }

    @BindingAdapter("textStyle")
    @JvmStatic
    fun setTextStyle(text: TextView, type: Int) {
        text.setTypeface(null, type)
    }

    @BindingAdapter("visibility")
    @JvmStatic
    fun visibility(view: View, visibility: Boolean) {
        view.visibility = if (visibility) View.VISIBLE else View.GONE
    }

    @BindingAdapter("visibility")
    @JvmStatic
    fun visibility(view: View, visibility: Int) {
        view.visibility = visibility
    }


    @BindingAdapter("enabled")
    @JvmStatic
    fun enabled(view: View, enabled: Boolean) {
        view.isEnabled = enabled
    }

    @BindingAdapter("textColor")
    @JvmStatic
    fun textColor(view: TextView, textColor: Int) {
        view.setTextColor(textColor)
    }

    @BindingAdapter("textColorHint")
    @JvmStatic
    fun textColorHint(view: TextView, textColor: Int) {
        view.setHintTextColor(textColor)
    }


    @BindingAdapter("view_data")
    @JvmStatic
    fun setViewData(view: RecyclerView, viewData: List<BaseBindingAdapterItem>) {
        view.setViewData(viewData)
    }
}